﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
using System.Web.Script.Serialization;
using log4net;
using Newtonsoft.Json;
namespace FlyComet
{
    public class AsyncRequest
    {
        private AsyncRequestState _asyncRequestState;
        private String _command;
        private static readonly ILog log = LogManager.GetLogger(typeof(AsyncRequest).Name);

        public AsyncRequest(AsyncRequestState ars)
        {
            _asyncRequestState = ars;
        }

        public void ProcessRequest()
        {
            // This is where the non-cpu-bound activity would take place, such as
            // accessing a Web Service, polling a slow piece of hardware, or 
            // performing a lengthy database operation. I put the thread to sleep 
            // for two seconds to simulate a lengthy operation.
            
            String cmd = _asyncRequestState.Context.Request["command"];
            _command = cmd.ToLower();
            LiveMessage fsqmsg = new LiveMessage();
            String requestid = "";
            String channelid = "";
            switch (_command)
            {
                case "connect":
                    fsqmsg.RequestId = System.Guid.NewGuid().ToString();
                    fsqmsg.StatusCode = 0;
                    fsqmsg.StatusDescription = "Id Generated Successfully";
                    fsqmsg.Message = fsqmsg.RequestId;
                    break;
                case "disconnect":
                    requestid = _asyncRequestState.Context.Request["requestkey"];
                    fsqmsg.RequestId = requestid;
                    fsqmsg.StatusCode = 0;
                    fsqmsg.StatusDescription = "Disconnected Successfully";
                    fsqmsg.Message = String.Format("Disconnected for {0} successfully", requestid);
                    break;
                case "subscribe":
                    requestid = _asyncRequestState.Context.Request["requestkey"];
                    channelid = _asyncRequestState.Context.Request["channel"];
                    log.Debug(String.Format("Subscribe request received for Requestid: {0}, channel:{1}", requestid, channelid));
                    if (String.IsNullOrEmpty(requestid) || String.IsNullOrEmpty(channelid))
                    {
                        return;
                    }
                    LiveMessageAggregator.SubscribeTopic(channelid, requestid);
                    fsqmsg.RequestId = requestid;
                    fsqmsg.StatusCode = 0;
                    fsqmsg.StatusDescription = "Subscribe success";
                    fsqmsg.Message = String.Format("{0} Subscribed for {1} successfully", channelid, requestid);
                    break;
                case "unsubscribe":
                    requestid = _asyncRequestState.Context.Request["requestkey"];
                    channelid = _asyncRequestState.Context.Request["channel"];
                    log.Debug(String.Format("UnSubscribe request received for Requestid: {0}, channel:{1}", requestid, channelid));
                    if (String.IsNullOrEmpty(requestid) || String.IsNullOrEmpty(channelid))
                    {
                        return;
                    }
                    LiveMessageAggregator.UnsubscribeTopic(channelid, requestid);
                    fsqmsg.RequestId = requestid;
                    fsqmsg.StatusCode = 0;
                    fsqmsg.StatusDescription = "Unsubscribe success";
                    fsqmsg.Message = String.Format("{0} Unsubscribed for {1} successfully", channelid, requestid);
                    break;

                case "post":
                    requestid = _asyncRequestState.Context.Request["requestkey"];
                    String message = _asyncRequestState.Context.Request["message"];
                    LiveMessageAggregator.PushMessage(message);
                    fsqmsg.RequestId = requestid;
                    fsqmsg.StatusCode = 0;
                    fsqmsg.StatusDescription = "Posted Successfully";
                    fsqmsg.Message = "Posted Successfully";
                    break;

                case "receive":
                    int numRequest = 0;
                    requestid = _asyncRequestState.Context.Request["requestkey"];
                    log.Debug(String.Format("Receive request received for Requestid: {0}", requestid));
                    if (String.IsNullOrEmpty(requestid))
                    {
                        return;
                    }
                    
                    List<JMSMessage> jmsmsgs = LiveMessageAggregator.GetPendingMessages(requestid);
                    ManualResetEvent manevent = new ManualResetEvent(false);
                    while (jmsmsgs.Count <= 0 && numRequest <= 5 )
                    {
                        manevent.WaitOne(3000);
                        jmsmsgs = LiveMessageAggregator.GetPendingMessages(requestid);
                        ++numRequest;
                    }
                    manevent.Close();
                    numRequest = 0;
                    string liveupdatedata = JsonConvert.SerializeObject(jmsmsgs);

                    fsqmsg.RequestId = requestid;
                    fsqmsg.StatusCode = jmsmsgs.Count > 0 ? 0 : 1;
                    fsqmsg.StatusDescription = jmsmsgs.Count <= 0 ? "No Data Found" : "Success";
                    fsqmsg.Message = liveupdatedata;
                    log.Debug(fsqmsg);
                    break;

            }

            string Serializeddata = JsonConvert.SerializeObject(fsqmsg);

            _asyncRequestState.Context.Response.Output.Write(Serializeddata);
            // tell asp.net I am finished processing this request
            _asyncRequestState.CompleteRequest();
        }
    }
}